package com.zsk.tool.encrypt;


import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.util.Base64;
import java.util.UUID;

/**
 * AES加密 https://www.cnblogs.com/xxoome/p/13927481.html
 *
 * @author: keke
 * @date: 2021/11/19 23:33
 */
public class AesEncrypt {
    // 256位密钥(32个字节) ，例如UUID去掉-刚好32个字节：b41bdbeec28e409a99aedef776a6f53f
    public static final String secret_key = "b41bdbeec28e409a99aedef776a6f53f";

    private static final String aes = "AES";

    // 初始向量IV, 初始向量IV的长度规定为128位16个字节, 初始向量的来源为随机生成.
    private static final byte[] iv = "skjtalkpoidwenzg".getBytes();
    // 加密解密算法/加密模式/填充方式
    private static final String cipher_algorithm = "AES/CBC/PKCS5Padding";

    static {
        Security.setProperty("crypto.policy", "unlimited");
    }

    /**
     * AES加密
     *
     * @param key     加密秘钥
     * @param content 加密内容
     * @return
     */
    public static String encode(String key, String content) throws NoSuchPaddingException, NoSuchAlgorithmException,
            InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        javax.crypto.SecretKey secretKey = new javax.crypto.spec.SecretKeySpec(key.getBytes(), aes);
        javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(cipher_algorithm);
        cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, secretKey, new javax.crypto.spec.IvParameterSpec(iv));
        // 获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
        byte[] byteEncode = content.getBytes(StandardCharsets.UTF_8);
        // 根据密码器的初始化方式加密
        byte[] byteAES = cipher.doFinal(byteEncode);
        // 将加密后的数据转换为字符串
        return Base64.getEncoder().encodeToString(byteAES);
    }


    /**
     * AES解密
     *
     * @param key     解密秘钥
     * @param content 解密内容
     * @return
     */
    public static String decode(String key, String content) throws NoSuchPaddingException, NoSuchAlgorithmException,
            BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException, InvalidKeyException {
        javax.crypto.SecretKey secretKey = new javax.crypto.spec.SecretKeySpec(key.getBytes(), aes);
        javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance(cipher_algorithm);
        cipher.init(javax.crypto.Cipher.DECRYPT_MODE, secretKey, new javax.crypto.spec.IvParameterSpec(iv));
        // 将加密并编码后的内容解码成字节数组
        byte[] byteContent = Base64.getDecoder().decode(content);
        // 解密
        byte[] byteDecode = cipher.doFinal(byteContent);
        return new String(byteDecode, StandardCharsets.UTF_8);
    }

    public static void main(String[] args) {
        try {
            String dbPassword = "123456abcdefghojklmn";
            String encryptDbPwd = AesEncrypt.encode(secret_key, dbPassword);
            System.out.println("encrypt: " + encryptDbPwd);
            String decrypt = AesEncrypt.decode(secret_key, encryptDbPwd);
            System.out.println("decrypt:" + decrypt);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
